📊 Vizualizasiya - Əsas Qrafiklər

Base R ilə Peşəkar Data Visualization

⏱️ Modul Müddəti: 2 saat | 📚 Səviyyə: Başlanğıc-Orta | 🎯 Praktik Ağırlıq: 95%


1 📊 8.1 Base R Qrafikləri (60 dəqiqə)

1.1 Demo Data Hazırlığı

# Comprehensive visualization dataset
set.seed(42)
n <- 120

# University students dataset for visualization
viz_data <- data.frame(
  student_id = 1:n,
  name = paste("Student", 1:n),
  age = sample(18:26, n, replace = TRUE, prob = c(0.15, 0.2, 0.25, 0.2, 0.1, 0.05, 0.03, 0.02, 0.01)),
  gender = sample(c("Kişi", "Qadın"), n, replace = TRUE, prob = c(0.48, 0.52)),
  faculty = sample(c("Mühəndislik", "Tibb", "İqtisadiyyat", "Hüquq", "IT", "Təbiət"), 
                  n, replace = TRUE, prob = c(0.25, 0.18, 0.18, 0.12, 0.22, 0.05)),
  course = sample(1:4, n, replace = TRUE, prob = c(0.3, 0.28, 0.25, 0.17)),
  
  # Academic scores with realistic correlations
  math_score = round(rnorm(n, 75, 12), 1),
  physics_score = round(rnorm(n, 72, 14), 1),
  chemistry_score = round(rnorm(n, 78, 10), 1),
  biology_score = round(rnorm(n, 76, 11), 1),
  
  # Study and lifestyle variables
  study_hours_week = round(pmax(5, rnorm(n, 28, 10)), 1),
  sleep_hours = round(pmax(4, pmin(12, rnorm(n, 7.2, 1.5))), 1),
  sports_hours = round(pmax(0, rnorm(n, 4, 3)), 1),
  
  # Financial and location
  family_income = round(rnorm(n, 2500, 800)),
  scholarship = sample(c(TRUE, FALSE), n, replace = TRUE, prob = c(0.32, 0.68)),
  city = sample(c("Bakı", "Gəncə", "Sumqayıt", "Mingəçevir", "Şirvan", "Digər"), 
               n, replace = TRUE, prob = c(0.42, 0.16, 0.13, 0.09, 0.08, 0.12)),
  
  # Satisfaction and performance metrics
  satisfaction_score = round(runif(n, 1, 10), 1),
  gpa = round(runif(n, 2.0, 4.0), 2),
  
  stringsAsFactors = FALSE
)

# Create realistic correlations
viz_data$physics_score <- viz_data$math_score * 0.8 + rnorm(n, 0, 8)
viz_data$gpa <- (viz_data$math_score + viz_data$physics_score + viz_data$chemistry_score) / 75 + rnorm(n, 0, 0.3)
viz_data$gpa <- pmax(2.0, pmin(4.0, viz_data$gpa))
viz_data$satisfaction_score <- viz_data$gpa * 2 + rnorm(n, 0, 1.5)
viz_data$satisfaction_score <- pmax(1, pmin(10, viz_data$satisfaction_score))

# Round final values
viz_data$physics_score <- round(viz_data$physics_score, 1)
viz_data$gpa <- round(viz_data$gpa, 2)
viz_data$satisfaction_score <- round(viz_data$satisfaction_score, 1)

# Add some missing values for realism
na_indices <- sample(1:n, 8)
viz_data$math_score[na_indices[1:3]] <- NA
viz_data$study_hours_week[na_indices[4:6]] <- NA
viz_data$family_income[na_indices[7:8]] <- NA

cat("=== VİZUALİZASİYA DATASETİ HAZIR ===\n")
#> === VİZUALİZASİYA DATASETİ HAZIR ===
cat("Tələbə sayı:", nrow(viz_data), "\n")
#> Tələbə sayı: 120
cat("Dəyişən sayı:", ncol(viz_data), "\n")
#> Dəyişən sayı: 18
cat("Fakültələr:", paste(unique(viz_data$faculty), collapse = ", "), "\n")
#> Fakültələr: Mühəndislik, İqtisadiyyat, Hüquq, IT, Tibb, Təbiət
head(viz_data)
#>   student_id      name age gender      faculty course math_score physics_score
#> 1          1 Student 1  23  Qadın  Mühəndislik      2       66.2          60.1
#> 2          2 Student 2  23  Qadın İqtisadiyyat      3       87.0          75.8
#> 3          3 Student 3  19   Kişi  Mühəndislik      1       90.1          79.6
#> 4          4 Student 4  22   Kişi  Mühəndislik      4       90.0          64.7
#> 5          5 Student 5  21   Kişi İqtisadiyyat      3       58.4          66.0
#> 6          6 Student 6  21  Qadın İqtisadiyyat      3       99.6          58.9
#>   chemistry_score biology_score study_hours_week sleep_hours sports_hours
#> 1            75.7          73.3             31.3         8.3          6.8
#> 2            58.8          80.6             42.7         6.2          4.5
#> 3            63.6          86.9               NA         5.5          1.3
#> 4            63.3          85.2             30.6         6.7          1.8
#> 5            85.6          68.7             31.3         7.3          5.2
#> 6            75.6          93.2             42.2         5.4          9.1
#>   family_income scholarship     city satisfaction_score  gpa
#> 1          2841       FALSE   Şirvan                7.2 2.93
#> 2          2272       FALSE     Bakı                4.0 2.91
#> 3          2009       FALSE     Bakı                4.0 3.11
#> 4          1824        TRUE     Bakı                6.7 3.33
#> 5          2623       FALSE   Şirvan                6.3 2.92
#> 6          1819        TRUE Sumqayıt                8.8 3.49
summary(viz_data[c("math_score", "physics_score", "study_hours_week", "gpa", "satisfaction_score")])
#>    math_score     physics_score   study_hours_week      gpa       
#>  Min.   : 42.60   Min.   :28.50   Min.   : 5.0     Min.   :2.000  
#>  1st Qu.: 65.90   1st Qu.:52.17   1st Qu.:19.3     1st Qu.:2.630  
#>  Median : 75.40   Median :59.60   Median :27.8     Median :2.890  
#>  Mean   : 74.89   Mean   :59.27   Mean   :26.6     Mean   :2.886  
#>  3rd Qu.: 83.80   3rd Qu.:66.00   3rd Qu.:32.2     3rd Qu.:3.112  
#>  Max.   :104.50   Max.   :89.20   Max.   :60.1     Max.   :4.000  
#>  NA's   :3                        NA's   :3                       
#>  satisfaction_score
#>  Min.   : 1.200    
#>  1st Qu.: 4.500    
#>  Median : 5.800    
#>  Mean   : 5.737    
#>  3rd Qu.: 6.800    
#>  Max.   :10.000    
#> 

1.2 plot() funksiyasının gücü

💡 plot() Universal: plot() funksiyası R-da ən universal qrafik funksiyasıdır - data tipinə görə avtomatik olaraq müvafiq qrafik növünü seçir.

# === PLOT() FUNKSİYASININ UNIVERSAL İSTİFADƏSİ ===

cat("=== PLOT() FUNKSİYASI - ƏSASLAR ===\n")
#> === PLOT() FUNKSİYASI - ƏSASLAR ===
# Clean data first - remove NA values for plotting
viz_data_clean <- viz_data[complete.cases(viz_data[c("math_score", "physics_score")]), ]

# 1. Numeric x numeric - Scatter plot (yalnız clean data ilə)
if(nrow(viz_data_clean) > 0) {
  plot(viz_data_clean$math_score, viz_data_clean$physics_score, 
       main = "Riyaziyyat vs Fizika Nəticələri",
       xlab = "Riyaziyyat Nəticəsi", 
       ylab = "Fizika Nəticəsi",
       col = "steelblue",
       pch = 16)  # Solid circles
  
  # Correlation line əlavə edək
  if(nrow(viz_data_clean) > 1) {
    abline(lm(physics_score ~ math_score, data = viz_data_clean), col = "red", lwd = 2)
  }
}

# 2. Factor x numeric - Box plot (NA-ları təmizlə)
viz_data_math_clean <- viz_data[!is.na(viz_data$math_score), ]
if(nrow(viz_data_math_clean) > 0) {
  plot(as.factor(viz_data_math_clean$faculty), viz_data_math_clean$math_score,
       main = "Fakültəyə görə Riyaziyyat Nəticələri",
       xlab = "Fakültə",
       ylab = "Riyaziyyat Nəticəsi",
       col = rainbow(length(unique(viz_data_math_clean$faculty))))
}

# 3. Numeric vector - Index plot (NA-ları təmizlə)
gpa_clean <- viz_data$gpa[!is.na(viz_data$gpa)]
if(length(gpa_clean) >= 30) {
  plot(gpa_clean[1:30],
       main = "İlk 30 Tələbənin GPA Trendi",
       xlab = "Tələbə İndeksi",
       ylab = "GPA",
       type = "b",  # Both points and lines
       col = "darkgreen",
       pch = 19)
} else if(length(gpa_clean) > 0) {
  plot(gpa_clean,
       main = paste("İlk", length(gpa_clean), "Tələbənin GPA Trendi"),
       xlab = "Tələbə İndeksi",
       ylab = "GPA",
       type = "b",
       col = "darkgreen",
       pch = 19)
}

# 4. Two factor variables - Mosaic-style
faculty_gender_table <- table(viz_data$faculty, viz_data$gender)
if(sum(faculty_gender_table) > 0) {
  plot(faculty_gender_table,
       main = "Fakültə və Cins Bölgüsü",
       xlab = "Fakültə",
       ylab = "Cins")
}

# 5. Different plot types demonstration
par(mfrow = c(2, 2))  # 2x2 layout

# Clean data for study hours and GPA
study_gpa_clean <- viz_data[complete.cases(viz_data[c("study_hours_week", "gpa")]), ]

# Type p - points only
if(nrow(study_gpa_clean) > 0) {
  plot(study_gpa_clean$study_hours_week, study_gpa_clean$gpa, 
       type = "p", main = "Type: Points", 
       xlab = "Oxu Saatları", ylab = "GPA", col = "blue", pch = 16)
}

# Type l - lines only  
satisfaction_clean <- viz_data$satisfaction_score[!is.na(viz_data$satisfaction_score)]
if(length(satisfaction_clean) >= 20) {
  plot(sort(satisfaction_clean[1:20]), 
       type = "l", main = "Type: Lines",
       xlab = "İndeks", ylab = "Məmnuniyyət", col = "red", lwd = 2)
} else if(length(satisfaction_clean) > 0) {
  plot(sort(satisfaction_clean), 
       type = "l", main = "Type: Lines",
       xlab = "İndeks", ylab = "Məmnuniyyət", col = "red", lwd = 2)
}

# Type b - both points and lines
if(length(gpa_clean) >= 15) {
  plot(sort(gpa_clean[1:15]), 
       type = "b", main = "Type: Both",
       xlab = "İndeks", ylab = "GPA", col = "green", pch = 17)
} else if(length(gpa_clean) > 0) {
  plot(sort(gpa_clean), 
       type = "b", main = "Type: Both",
       xlab = "İndeks", ylab = "GPA", col = "green", pch = 17)
}

# Type h - histogram-like vertical lines
age_clean <- viz_data$age[!is.na(viz_data$age)]
if(length(age_clean) >= 20) {
  plot(age_clean[1:20], 
       type = "h", main = "Type: Histogram-like",
       xlab = "İndeks", ylab = "Yaş", col = "purple", lwd = 3)
} else if(length(age_clean) > 0) {
  plot(age_clean, 
       type = "h", main = "Type: Histogram-like",
       xlab = "İndeks", ylab = "Yaş", col = "purple", lwd = 3)
}

par(mfrow = c(1, 1))  # Reset layout

# 6. Advanced plot() customization
cat("\n=== QABAQCIL PLOT() CUSTOMIZATION ===\n")
#> 
#> === QABAQCIL PLOT() CUSTOMIZATION ===
# Create a comprehensive scatter plot with clean data
study_gpa_complete <- viz_data[complete.cases(viz_data[c("study_hours_week", "gpa", "scholarship")]), ]

if(nrow(study_gpa_complete) > 0) {
  # Safe xlim və ylim hesablama
  x_range <- range(study_gpa_complete$study_hours_week, na.rm = TRUE)
  y_range <- range(study_gpa_complete$gpa, na.rm = TRUE)
  
  plot(study_gpa_complete$study_hours_week, study_gpa_complete$gpa,
       main = "Oxu Saatları və GPA Əlaqəsi\n(Detallı Analiz)",
       xlab = "Həftəlik Oxu Saatları",
       ylab = "GPA (4.0 miqyasında)",
       
       # Point customization
       pch = 21,  # Circle with border
       bg = ifelse(study_gpa_complete$scholarship, "gold", "lightblue"),  # Fill color
       col = ifelse(study_gpa_complete$scholarship, "orange", "blue"),    # Border color
       cex = 1.2,  # Point size
       
       # Safe axis customization
       xlim = c(max(0, x_range[1] - 2), x_range[2] + 5),
       ylim = c(max(1.5, y_range[1] - 0.2), min(4.2, y_range[2] + 0.2)),
       
       # Grid and background
       panel.first = {
         grid(col = "lightgray", lty = "dotted")
         rect(par("usr")[1], par("usr")[3], par("usr")[2], par("usr")[4], 
              col = "ivory")
       })
  
  # Add legend
  legend("bottomright", 
         legend = c("Təqaüdlü", "Təqaüdsüz"),
         pch = 21,
         pt.bg = c("gold", "lightblue"),
         col = c("orange", "blue"),
         cex = 0.9,
         bg = "white")
  
  # Add trend line and statistics (yalnız kifayət qədər data varsa)
  if(nrow(study_gpa_complete) > 2) {
    lm_model <- lm(gpa ~ study_hours_week, data = study_gpa_complete)
    abline(lm_model, col = "red", lwd = 2, lty = 2)
    
    # Add correlation text
    cor_value <- cor(study_gpa_complete$study_hours_week, study_gpa_complete$gpa, use = "complete.obs")
    if(!is.na(cor_value)) {
      text(x_range[1] + 2, y_range[2] - 0.1, paste("r =", round(cor_value, 3)), 
           col = "red", font = 2, cex = 1.1)
    }
  }
}

# 7. Interactive-style plot with identification (safeguarded)
plot_with_outliers <- function(x, y, labels, main_title) {
  # Clean data first
  complete_cases <- complete.cases(x, y, labels)
  
  if(sum(complete_cases) == 0) {
    plot(1, 1, type = "n", main = "No complete data available")
    return(invisible(NULL))
  }
  
  x_clean <- x[complete_cases]
  y_clean <- y[complete_cases]
  labels_clean <- labels[complete_cases]
  
  if(length(x_clean) < 2) {
    plot(x_clean, y_clean, main = main_title,
         xlab = deparse(substitute(x)),
         ylab = deparse(substitute(y)),
         pch = 16, col = "steelblue", cex = 1.1)
    return(invisible(NULL))
  }
  
  plot(x_clean, y_clean, main = main_title,
       xlab = deparse(substitute(x)),
       ylab = deparse(substitute(y)),
       pch = 16, col = "steelblue", cex = 1.1)
  
  # Identify outliers (beyond 2 SD) - yalnız kifayət qədər data varsa
  if(length(x_clean) > 5) {
    x_outliers <- abs(scale(x_clean)) > 2
    y_outliers <- abs(scale(y_clean)) > 2
    outliers <- x_outliers | y_outliers
    
    if(any(outliers, na.rm = TRUE)) {
      points(x_clean[outliers], y_clean[outliers], col = "red", pch = 17, cex = 1.5)
      text(x_clean[outliers], y_clean[outliers], labels_clean[outliers], 
           pos = 3, col = "red", font = 2, cex = 0.8)
    }
    
    # Add statistics
    if(length(x_clean) > 2) {
      abline(lm(y_clean ~ x_clean), col = "red", lty = 2)
      cor_val <- cor(x_clean, y_clean, use = "complete.obs")
      if(!is.na(cor_val)) {
        legend("topright", 
               legend = paste("Correlation:", round(cor_val, 3)),
               bty = "n", text.col = "red")
      }
    }
  }
}

# Test outlier detection plot with clean data
family_satisfaction_complete <- viz_data[complete.cases(viz_data[c("family_income", "satisfaction_score", "name")]), ]

if(nrow(family_satisfaction_complete) > 0) {
  plot_with_outliers(family_satisfaction_complete$family_income, 
                    family_satisfaction_complete$satisfaction_score, 
                    family_satisfaction_complete$name, 
                    "Ailə Gəliri vs Məmnuniyyət")
}

1.3 Scatter plots (nöqtə qrafikləri)

# === SCATTER PLOTS - DETALLI ANALİZ ===

cat("=== SCATTER PLOTS MÜXTƏLİF NÖVLƏRİ ===\n")
#> === SCATTER PLOTS MÜXTƏLİF NÖVLƏRİ ===
# Clean data for all scatter plots
clean_data <- viz_data[complete.cases(viz_data[c("math_score", "physics_score", "study_hours_week", "gpa")]), ]

# 1. Sadə scatter plot
plot(clean_data$math_score, clean_data$physics_score,
     main = "Riyaziyyat və Fizika Nəticələri",
     xlab = "Riyaziyyat Nəticəsi",
     ylab = "Fizika Nəticəsi",
     pch = 19,
     col = "darkblue")

# 2. Qruplara görə rənglənmiş scatter plot
colors_by_faculty <- rainbow(length(unique(clean_data$faculty)))
faculty_colors <- colors_by_faculty[as.numeric(as.factor(clean_data$faculty))]

plot(clean_data$math_score, clean_data$physics_score,
     main = "Riyaziyyat vs Fizika (Fakültəyə görə)",
     xlab = "Riyaziyyat",
     ylab = "Fizika",
     pch = 19,
     col = faculty_colors,
     cex = 1.2)

# Legend əlavə et
legend("bottomright", 
       legend = unique(clean_data$faculty),
       col = colors_by_faculty,
       pch = 19,
       cex = 0.8,
       bg = "white")

# 3. Bubble plot (3rd dimension as size)
plot(clean_data$study_hours_week, clean_data$gpa,
     main = "Oxu Saatları vs GPA\n(Qabar ölçüsü: Yaş)",
     xlab = "Həftəlik Oxu Saatları",
     ylab = "GPA",
     pch = 21,
     bg = "lightblue",
     col = "darkblue",
     cex = clean_data$age / 10)  # Size proportional to age

# Add size legend
legend("bottomright",
       legend = c("18 yaş", "22 yaş", "26 yaş"),
       pch = 21,
       pt.bg = "lightblue",
       col = "darkblue",
       pt.cex = c(1.8, 2.2, 2.6),
       title = "Yaş",
       bg = "white")

# 4. Multi-dimensional scatter plot
par(mfrow = c(2, 2))

# Math vs Physics colored by GPA
gpa_colors <- colorRampPalette(c("red", "yellow", "green"))(100)
gpa_color_indices <- cut(clean_data$gpa, breaks = 100, labels = FALSE)

plot(clean_data$math_score, clean_data$physics_score,
     main = "Rəngli GPA ilə",
     xlab = "Riyaziyyat", ylab = "Fizika",
     pch = 19,
     col = gpa_colors[gpa_color_indices],
     cex = 1.2)

# Study hours vs GPA colored by satisfaction
satisfaction_clean <- clean_data[!is.na(clean_data$satisfaction_score), ]
satisfaction_colors <- colorRampPalette(c("darkred", "orange", "lightgreen"))(100)
satisfaction_indices <- cut(satisfaction_clean$satisfaction_score, breaks = 100, labels = FALSE)

plot(satisfaction_clean$study_hours_week, satisfaction_clean$gpa,
     main = "Rəngli Məmnuniyyətlə",
     xlab = "Oxu Saatları", ylab = "GPA",
     pch = 19,
     col = satisfaction_colors[satisfaction_indices],
     cex = 1.2)

# Family income vs GPA with different shapes by gender
income_gpa_clean <- viz_data[complete.cases(viz_data[c("family_income", "gpa", "gender")]), ]
plot(income_gpa_clean$family_income, income_gpa_clean$gpa,
     main = "Gəlir vs GPA (Cinslə)",
     xlab = "Ailə Gəliri", ylab = "GPA",
     pch = ifelse(income_gpa_clean$gender == "Kişi", 17, 19),  # Triangle vs circle
     col = ifelse(income_gpa_clean$gender == "Kişi", "blue", "red"),
     cex = 1.3)

legend("topright", 
       legend = c("Kişi", "Qadın"),
       pch = c(17, 19),
       col = c("blue", "red"),
       cex = 0.9)

# Age vs satisfaction with scholarship highlighting
age_satisfaction_clean <- viz_data[complete.cases(viz_data[c("age", "satisfaction_score", "scholarship")]), ]
plot(age_satisfaction_clean$age, age_satisfaction_clean$satisfaction_score,
     main = "Yaş vs Məmnuniyyət",
     xlab = "Yaş", ylab = "Məmnuniyyət",
     pch = ifelse(age_satisfaction_clean$scholarship, 17, 1),  # Filled vs empty
     col = ifelse(age_satisfaction_clean$scholarship, "gold", "gray"),
     cex = 1.4)

legend("topright",
       legend = c("Təqaüdlü", "Təqaüdsüz"),
       pch = c(17, 1),
       col = c("gold", "gray"))

par(mfrow = c(1, 1))

# 5. Advanced scatter plot with regression analysis
advanced_scatter <- function(x, y, data, x_name, y_name, group_var = NULL) {
  
  # Clean data first
  if(is.null(group_var)) {
    complete_cases <- complete.cases(x, y)
    x_clean <- x[complete_cases]
    y_clean <- y[complete_cases]
    
    plot(x_clean, y_clean,
         main = paste("Detallı Analiz:", x_name, "vs", y_name),
         xlab = x_name,
         ylab = y_name,
         pch = 16,
         col = "steelblue",
         cex = 1.2)
    
    # Simple regression
    lm_model <- lm(y_clean ~ x_clean)
    abline(lm_model, col = "red", lwd = 2)
    
    # Statistics
    r_sq <- summary(lm_model)$r.squared
    cor_val <- cor(x_clean, y_clean, use = "complete.obs")
    
    legend("topright",
           legend = c(paste("R² =", round(r_sq, 3)),
                     paste("r =", round(cor_val, 3))),
           bty = "n",
           text.col = "red")
    
  } else {
    # Grouped scatter plot
    complete_cases <- complete.cases(x, y, group_var)
    x_clean <- x[complete_cases]
    y_clean <- y[complete_cases]
    group_clean <- group_var[complete_cases]
    
    groups <- unique(group_clean)
    colors <- rainbow(length(groups))
    
    plot(x_clean, y_clean,
         main = paste("Qruplu Analiz:", x_name, "vs", y_name),
         xlab = x_name,
         ylab = y_name,
         pch = 16,
         col = colors[as.numeric(as.factor(group_clean))],
         cex = 1.2)
    
    # Regression lines for each group
    for(i in 1:length(groups)) {
      group_data <- group_clean == groups[i]
      if(sum(group_data, na.rm = TRUE) > 3) {
        lm_group <- lm(y_clean[group_data] ~ x_clean[group_data])
        abline(lm_group, col = colors[i], lwd = 2, lty = 2)
      }
    }
    
    legend("topright",
           legend = groups,
           col = colors,
           pch = 16,
           cex = 0.8)
  }
}

# Test advanced scatter plot
clean_for_advanced <- viz_data[complete.cases(viz_data[c("study_hours_week", "gpa", "faculty")]), ]
advanced_scatter(clean_for_advanced$study_hours_week, clean_for_advanced$gpa, clean_for_advanced,
                "Həftəlik Oxu Saatları", "GPA", clean_for_advanced$faculty)

1.4 Line plots (xətt qrafikləri)

# === LINE PLOTS - TİME SERİES VƏ TREND ANALİZİ ===

cat("=== LINE PLOTS MÜXTƏLİF NÖVLƏRİ ===\n")
#> === LINE PLOTS MÜXTƏLİF NÖVLƏRİ ===
# Clean data for line plots
gpa_clean <- viz_data$gpa[!is.na(viz_data$gpa)]

# 1. Sadə line plot - GPA trend
sorted_indices <- order(gpa_clean)
plot(1:length(sorted_indices), gpa_clean[sorted_indices],
     type = "l",
     main = "GPA Sıralama Trendi",
     xlab = "Tələbə Sıralaması",
     ylab = "GPA",
     col = "darkgreen",
     lwd = 2)

# Points əlavə et
points(1:length(sorted_indices), gpa_clean[sorted_indices],
       pch = 19, col = "red", cex = 0.6)

# 2. Çoxlu xətt qrafiki - fənnlər üzrə performans
# Get students with complete scores for all subjects
complete_scores <- viz_data[complete.cases(viz_data[c("math_score", "physics_score", "chemistry_score", "biology_score")]), ]
sample_students <- sample(1:nrow(complete_scores), min(5, nrow(complete_scores)))

plot(1, type = "n",
     xlim = c(1, 4),
     ylim = c(40, 100),
     main = "5 Tələbənin Fənn Performansları",
     xlab = "Fənn",
     ylab = "Nəticə",
     xaxt = "n")

# X axis labels
axis(1, at = 1:4, labels = c("Riyaziyyat", "Fizika", "Kimya", "Biologiya"))

# Add lines for each student
colors <- rainbow(length(sample_students))
for(i in 1:length(sample_students)) {
  student_idx <- sample_students[i]
  student_data <- complete_scores[student_idx, ]
  scores <- c(student_data$math_score,
              student_data$physics_score,
              student_data$chemistry_score,
              student_data$biology_score)
  
  lines(1:4, scores, col = colors[i], lwd = 2, type = "b", pch = 19)
}

legend("topright",
       legend = paste("Tələbə", sample_students),
       col = colors,
       lwd = 2,
       pch = 19,
       cex = 0.8)

# 3. Fakültəyə görə orta performans trendi
faculty_means <- aggregate(viz_data[c("math_score", "physics_score", "chemistry_score", "biology_score")],
                          by = list(Faculty = viz_data$faculty),
                          FUN = function(x) mean(x, na.rm = TRUE))

# Plot setup
plot(1, type = "n",
     xlim = c(1, 4),
     ylim = c(60, 85),
     main = "Fakültələrin Fənn Ortalamaları",
     xlab = "Fənn",
     ylab = "Orta Nəticə",
     xaxt = "n")

axis(1, at = 1:4, labels = c("Riyaziyyat", "Fizika", "Kimya", "Biologiya"))

# Add faculty lines
faculty_colors <- rainbow(nrow(faculty_means))
for(i in 1:nrow(faculty_means)) {
  scores <- as.numeric(faculty_means[i, 2:5])
  lines(1:4, scores, 
        col = faculty_colors[i], 
        lwd = 3, 
        type = "b", 
        pch = 19,
        cex = 1.2)
}

legend("topright",
       legend = faculty_means$Faculty,
       col = faculty_colors,
       lwd = 3,
       pch = 19,
       cex = 0.7)

# Add grid for better readability
grid(col = "lightgray", lty = "dotted")

# 4. Age-based performance trend
age_performance <- aggregate(viz_data[c("math_score", "gpa", "satisfaction_score")],
                           by = list(Age = viz_data$age),
                           FUN = function(x) mean(x, na.rm = TRUE))

par(mfrow = c(1, 2))

# Math score by age
plot(age_performance$Age, age_performance$math_score,
     type = "b",
     main = "Yaşa görə Riyaziyyat Performansı",
     xlab = "Yaş",
     ylab = "Orta Riyaziyyat Nəticəsi",
     col = "blue",
     lwd = 2,
     pch = 19,
     cex = 1.3)

# Add smooth trend line
if(nrow(age_performance) > 3) {
  trend_model <- loess(math_score ~ Age, data = age_performance)
  lines(age_performance$Age, predict(trend_model), col = "red", lwd = 3, lty = 2)
}

# GPA by age
plot(age_performance$Age, age_performance$gpa,
     type = "b",
     main = "Yaşa görə GPA Trendi",
     xlab = "Yaş",
     ylab = "Orta GPA",
     col = "darkgreen",
     lwd = 2,
     pch = 17,
     cex = 1.3)

# Add trend line
if(nrow(age_performance) > 3) {
  trend_gpa <- loess(gpa ~ Age, data = age_performance)
  lines(age_performance$Age, predict(trend_gpa), col = "orange", lwd = 3, lty = 2)
}

par(mfrow = c(1, 1))

# 5. Time series simulation - semester progress
simulate_semester_progress <- function() {
  weeks <- 1:15
  set.seed(123)
  
  # Simulate different student types
  excellent_student <- 85 + cumsum(rnorm(15, 0.5, 2))
  average_student <- 75 + cumsum(rnorm(15, 0.2, 2.5))
  struggling_student <- 65 + cumsum(rnorm(15, -0.1, 3))
  
  plot(weeks, excellent_student,
       type = "l",
       main = "Semestr Ərzində Performans Trendi",
       xlab = "Həftə",
       ylab = "Orta Qiymət",
       col = "green",
       lwd = 3,
       ylim = c(50, 100))
  
  lines(weeks, average_student, col = "blue", lwd = 3)
  lines(weeks, struggling_student, col = "red", lwd = 3)
  
  # Add points
  points(weeks, excellent_student, pch = 19, col = "green", cex = 0.8)
  points(weeks, average_student, pch = 17, col = "blue", cex = 0.8)
  points(weeks, struggling_student, pch = 15, col = "red", cex = 0.8)
  
  legend("topleft",
         legend = c("Mükəmməl Tələbə", "Orta Tələbə", "Çətinlik Çəkən"),
         col = c("green", "blue", "red"),
         lwd = 3,
         pch = c(19, 17, 15),
         bg = "white")
  
  grid(col = "lightgray", lty = "dotted")
}

simulate_semester_progress()

1.5 Bar plots (sütun qrafikləri)

# === BAR PLOTS - KATEQORİK DATA ANALİZİ ===

cat("=== BAR PLOTS MÜXTƏLİF NÖVLƏRİ ===\n")
#> === BAR PLOTS MÜXTƏLİF NÖVLƏRİ ===
# 1. Sadə bar plot - Fakültə tezliyi
faculty_counts <- table(viz_data$faculty)
barplot(faculty_counts,
        main = "Fakültə üzrə Tələbə Sayı",
        xlab = "Fakültə",
        ylab = "Tələbə Sayı",
        col = rainbow(length(faculty_counts)),
        border = "black",
        las = 2)  # Rotate labels

# Add value labels on bars
text(x = seq_along(faculty_counts), 
     y = faculty_counts + 1, 
     labels = faculty_counts, 
     pos = 3, 
     font = 2)

# 2. Horizontal bar plot
par(mar = c(5, 8, 4, 2))  # Increase left margin
barplot(sort(faculty_counts),
        main = "Fakültə Bölgüsü (Sıralı)",
        xlab = "Tələbə Sayı",
        col = heat.colors(length(faculty_counts)),
        border = "darkblue",
        horiz = TRUE,
        las = 1)

par(mar = c(5, 4, 4, 2))  # Reset margins

# 3. Grouped bar plot - Fakültə və cins
faculty_gender_table <- table(viz_data$faculty, viz_data$gender)
barplot(faculty_gender_table,
        main = "Fakültə və Cins Bölgüsü",
        xlab = "Cins",
        ylab = "Tələbə Sayı",
        col = rainbow(nrow(faculty_gender_table)),
        legend = rownames(faculty_gender_table),
        beside = TRUE,  # Side by side bars
        border = "black")

# 4. Stacked bar plot
barplot(faculty_gender_table,
        main = "Yığılmış Fakültə və Cins Bölgüsü",
        xlab = "Cins",
        ylab = "Tələbə Sayı",
        col = rainbow(nrow(faculty_gender_table)),
        legend = rownames(faculty_gender_table),
        border = "white")

# 5. Percentage stacked bar plot
faculty_gender_pct <- prop.table(faculty_gender_table, 2) * 100
barplot(faculty_gender_pct,
        main = "Cins Daxilində Fakültə Faizləri",
        xlab = "Cins",
        ylab = "Faiz (%)",
        col = rainbow(nrow(faculty_gender_pct)),
        legend = rownames(faculty_gender_pct),
        border = "white")

# Add 100% line
abline(h = 100, col = "red", lty = 2, lwd = 2)

# 6. Performance-based bar plot
# Create GPA categories
gpa_clean_for_categories <- viz_data$gpa[!is.na(viz_data$gpa)]
gpa_categories <- cut(gpa_clean_for_categories, 
                     breaks = c(0, 2.5, 3.0, 3.5, 4.0),
                     labels = c("Aşağı", "Orta", "Yaxşı", "Əla"),
                     include.lowest = TRUE)

gpa_counts <- table(gpa_categories)
colors_gpa <- c("red", "orange", "lightgreen", "darkgreen")

barplot(gpa_counts,
        main = "GPA Performans Bölgüsü",
        xlab = "GPA Kateqoriyası",
        ylab = "Tələbə Sayı",
        col = colors_gpa,
        border = "black",
        cex.names = 1.2)

# Add percentage labels
percentages <- round(prop.table(gpa_counts) * 100, 1)
text(x = seq_along(gpa_counts), 
     y = gpa_counts + 2, 
     labels = paste0(percentages, "%"), 
     pos = 3, 
     font = 2,
     col = "darkblue")

1.6 Histogramlar

# === HISTOGRAMLAR - DAĞILIM ANALİZİ ===

cat("=== HİSTOQRAMLAR MÜXTƏLİF NÖVLƏRİ ===\n")
#> === HİSTOQRAMLAR MÜXTƏLİF NÖVLƏRİ ===
# Clean data for histograms
math_clean <- viz_data$math_score[!is.na(viz_data$math_score)]
gpa_clean <- viz_data$gpa[!is.na(viz_data$gpa)]

# 1. Sadə histogram - Math scores
hist(math_clean,
     main = "Riyaziyyat Nəticələrinin Paylanması",
     xlab = "Riyaziyyat Nəticəsi",
     ylab = "Tezlik",
     col = "lightblue",
     border = "darkblue",
     breaks = 15)

# Add vertical lines for mean and median
mean_math <- mean(math_clean, na.rm = TRUE)
median_math <- median(math_clean, na.rm = TRUE)

abline(v = mean_math, col = "red", lwd = 3, lty = 1)
abline(v = median_math, col = "blue", lwd = 3, lty = 2)

legend("topright",
       legend = c(paste("Orta:", round(mean_math, 1)),
                  paste("Median:", round(median_math, 1))),
       col = c("red", "blue"),
       lwd = 3,
       lty = c(1, 2),
       bg = "white")

# 2. Density histogram with normal curve overlay
hist(gpa_clean,
     main = "GPA Paylanması və Normal Əyri",
     xlab = "GPA",
     ylab = "Sıxlıq",
     col = "lightyellow",
     border = "orange",
     breaks = 20,
     freq = FALSE)  # Density instead of frequency

# Add density curve
lines(density(gpa_clean, na.rm = TRUE), col = "red", lwd = 3)

# Add normal distribution overlay
x_seq <- seq(min(gpa_clean, na.rm = TRUE), max(gpa_clean, na.rm = TRUE), length = 100)
normal_curve <- dnorm(x_seq, mean = mean(gpa_clean, na.rm = TRUE), 
                     sd = sd(gpa_clean, na.rm = TRUE))
lines(x_seq, normal_curve, col = "blue", lwd = 3, lty = 2)

legend("topright",
       legend = c("Faktiki Sıxlıq", "Normal Paylanma"),
       col = c("red", "blue"),
       lwd = 3,
       lty = c(1, 2),
       bg = "white")

# 3. Multiple histograms comparison
par(mfrow = c(2, 2))

# Different subjects (clean data)
math_clean <- viz_data$math_score[!is.na(viz_data$math_score)]
physics_clean <- viz_data$physics_score[!is.na(viz_data$physics_score)]
chemistry_clean <- viz_data$chemistry_score[!is.na(viz_data$chemistry_score)]
biology_clean <- viz_data$biology_score[!is.na(viz_data$biology_score)]

hist(math_clean, main = "Riyaziyyat", col = "lightblue", 
     xlab = "Nəticə", breaks = 10)
hist(physics_clean, main = "Fizika", col = "lightgreen", 
     xlab = "Nəticə", breaks = 10)
hist(chemistry_clean, main = "Kimya", col = "lightyellow", 
     xlab = "Nəticə", breaks = 10)
hist(biology_clean, main = "Biologiya", col = "lightpink", 
     xlab = "Nəticə", breaks = 10)

par(mfrow = c(1, 1))

# 4. Overlapping histograms by group
# Separate by gender (clean data)
male_math <- viz_data$math_score[viz_data$gender == "Kişi" & !is.na(viz_data$math_score)]
female_math <- viz_data$math_score[viz_data$gender == "Qadın" & !is.na(viz_data$math_score)]

# Create overlapping histograms
hist(male_math, 
     main = "Cinsə görə Riyaziyyat Nəticələri",
     xlab = "Riyaziyyat Nəticəsi",
     ylab = "Tezlik",
     col = rgb(0, 0, 1, 0.5),  # Semi-transparent blue
     border = "darkblue",
     breaks = 15,
     xlim = range(c(male_math, female_math), na.rm = TRUE))

hist(female_math,
     col = rgb(1, 0, 0, 0.5),  # Semi-transparent red
     border = "darkred",
     breaks = 15,
     add = TRUE)

legend("topright",
       legend = c("Kişi", "Qadın"),
       col = c(rgb(0, 0, 1, 0.5), rgb(1, 0, 0, 0.5)),
       pch = 15,
       cex = 1.2,
       bg = "white")

2 === BOX PLOTS - PAYLANMA VƏ OUTLIER ANALİZİ ===

cat(“=== BOX PLOTS MÜXTƏLİF NÖVLƏRİ ===”)

3 Clean data for box plots

math_clean <- viz_data\(math_score[!is.na(viz_data\)math_score)]

4 1. Sadə box plot - Math scores

if(length(math_clean) > 0) { boxplot(math_clean, main = “Riyaziyyat Nəticələrinin Paylanması”, ylab = “Riyaziyyat Nəticəsi”, col = “lightblue”, border = “darkblue”, notch = TRUE, # Confidence interval around median outline = TRUE) # Show outliers

# Add statistics as text math_stats <- summary(math_clean) mean_val <- mean(math_clean, na.rm = TRUE) if(!is.na(mean_val)) { text(1.3, math_stats[4], paste(“Orta:”, round(mean_val, 1)), pos = 4, font = 2, col = “red”) } }

5 2. Multiple box plots by group - Faculty comparison

6 Clean data for faculty comparison

faculty_math_clean <- viz_data[!is.na(viz_data\(math_score) & !is.na(viz_data\)faculty), ]

if(nrow(faculty_math_clean) > 0) { # Ensure faculty is a factor and has valid levels faculty_math_clean\(faculty <- as.factor(faculty_math_clean\)faculty) faculty_math_clean <- faculty_math_clean[!is.na(faculty_math_clean$faculty), ]

if(nrow(faculty_math_clean) > 0) { boxplot(math_score ~ faculty, data = faculty_math_clean, main = “Fakültəyə görə Riyaziyyat Nəticələri”, xlab = “Fakültə”, ylab = “Riyaziyyat Nəticəsi”, col = rainbow(length(unique(faculty_math_clean$faculty))), border = “black”, las = 2, # Rotate x-axis labels notch = TRUE)

# Add grand mean line
grand_mean <- mean(faculty_math_clean$math_score, na.rm = TRUE)
if(!is.na(grand_mean)) {
  abline(h = grand_mean, col = "red", lwd = 2, lty = 2)
  text(1, grand_mean + 3, paste("Ümumi Orta:", round(grand_mean, 1)), 
       col = "red", font = 2)
}

} }

7 3. Side-by-side comparison - Gender

par(mfrow = c(1, 2))

8 Math by gender

gender_math_clean <- viz_data[!is.na(viz_data\(math_score) & !is.na(viz_data\)gender), ] if(nrow(gender_math_clean) > 0) { gender_math_clean\(gender <- as.factor(gender_math_clean\)gender)

boxplot(math_score ~ gender, data = gender_math_clean, main = “Cinsə görə Riyaziyyat”, xlab = “Cins”, ylab = “Riyaziyyat Nəticəsi”, col = c(“lightpink”, “lightblue”), border = “black”, notch = TRUE) }

9 GPA by gender

gender_gpa_clean <- viz_data[!is.na(viz_data\(gpa) & !is.na(viz_data\)gender), ] if(nrow(gender_gpa_clean) > 0) { gender_gpa_clean\(gender <- as.factor(gender_gpa_clean\)gender)

boxplot(gpa ~ gender, data = gender_gpa_clean, main = “Cinsə görə GPA”, xlab = “Cins”, ylab = “GPA”, col = c(“lightpink”, “lightblue”), border = “black”, notch = TRUE) }

par(mfrow = c(1, 1))

10 4. Advanced box plot with multiple comparisons

cat(“=== QABAQCIL BOX PLOT ANALİZİ ===”)

11 Course level comparison

course_math_clean <- viz_data[!is.na(viz_data\(math_score) & !is.na(viz_data\)course), ] if(nrow(course_math_clean) > 0) { course_math_clean\(course <- as.factor(course_math_clean\)course)

boxplot(math_score ~ course, data = course_math_clean, main = “Kurs Səviyyəsinə görə Riyaziyyat Performansı”, xlab = “Kurs”, ylab = “Riyaziyyat Nəticəsi”, col = heat.colors(length(unique(course_math_clean$course))), border = “darkred”, notch = TRUE)

# Add mean points course_means <- tapply(course_math_clean\(math_score, course_math_clean\)course, mean, na.rm = TRUE) points(1:length(course_means), course_means, pch = 18, col = “red”, cex = 2)

legend(“topright”, legend = “Orta dəyərlər”, pch = 18, col = “red”, cex = 1.2, bg = “white”) }

12 5. Comparative analysis across subjects

subjects_data <- viz_data[complete.cases(viz_data[c(“math_score”, “physics_score”, “chemistry_score”, “biology_score”)]), ]

if(nrow(subjects_data) > 0) { # Reshape data for comparison subjects_long <- data.frame( score = c(subjects_data\(math_score, subjects_data\)physics_score, subjects_data\(chemistry_score, subjects_data\)biology_score), subject = rep(c(“Riyaziyyat”, “Fizika”, “Kimya”, “Biologiya”), each = nrow(subjects_data)) )

# Remove any remaining NA values subjects_long <- subjects_long[!is.na(subjects_long$score), ]

if(nrow(subjects_long) > 0) { subjects_long\(subject <- as.factor(subjects_long\)subject)

boxplot(score ~ subject, data = subjects_long,
        main = "Fənnlər Arasında Performans Müqayisəsi",
        xlab = "Fənn",
        ylab = "Nəticə",
        col = c("lightblue", "lightgreen", "lightyellow", "lightpink"),
        border = "black",
        las = 2,
        notch = TRUE)

# Add overall statistics
overall_mean <- mean(subjects_long$score, na.rm = TRUE)
abline(h = overall_mean, col = "red", lwd = 2, lty = 2)
text(2, overall_mean + 5, paste("Ümumi Orta:", round(overall_mean, 1)), 
     col = "red", font = 2)

} }

13 6. Box plot with violin-like enhancements

enhanced_boxplot <- function(data_col, group_col, main_title, xlab_text, ylab_text) { # Clean data clean_data <- data.frame( value = data_col, group = group_col ) clean_data <- clean_data[complete.cases(clean_data), ]

if(nrow(clean_data) == 0) { plot(1, 1, type = “n”, main = “No data available”) return(invisible(NULL)) }

clean_data\(group <- as.factor(clean_data\)group)

# Create enhanced boxplot boxplot(value ~ group, data = clean_data, main = main_title, xlab = xlab_text, ylab = ylab_text, col = rainbow(length(unique(clean_data$group)), alpha = 0.7), border = “black”, notch = TRUE, outline = FALSE) # Remove outliers for cleaner look

# Add individual points with jitter for(i in 1:length(unique(clean_data\(group))) { group_name <- unique(clean_data\)group)[i] group_data <- clean_data\(value[clean_data\)group == group_name]

if(length(group_data) > 0) {
  x_pos <- rep(i, length(group_data)) + runif(length(group_data), -0.2, 0.2)
  points(x_pos, group_data, 
         pch = 19, 
         col = rgb(0, 0, 0, alpha = 0.3), 
         cex = 0.5)
}

}

# Add mean markers group_means <- tapply(clean_data\(value, clean_data\)group, mean, na.rm = TRUE) points(1:length(group_means), group_means, pch = 18, col = “red”, cex = 2)

legend(“topright”, legend = c(“Median”, “Mean”, “Data Points”), pch = c(“|”, 18, 19), col = c(“black”, “red”, rgb(0, 0, 0, alpha = 0.3)), bg = “white”, cex = 0.9) }

14 Test enhanced boxplot

if(nrow(viz_data) > 0) { enhanced_boxplot(viz_data\(satisfaction_score, viz_data\)faculty, “Fakültəyə görə Məmnuniyyət Səviyyəsi (Enhanced)”, “Fakültə”, “Məmnuniyyət Səviyyəsi”) }


---

# 🎨 8.2 Qrafik Parametrləri (45 dəqiqə)

## Rənglər əlavə etmə

<div class="alert alert-info">
<strong>🎨 Rəng Sistemi:</strong> R-da rəngləri müxtəlif üsullarla təyin edə bilərsiniz - ad ilə, hex kodları ilə, RGB dəyərləri ilə və ya hazır rəng paletləri ilə.
</div>


``` r
# === RƏNG SİSTEMLƏRİ VƏ PALETLƏRİ ===

cat("=== R-DA RƏNG SİSTEMLƏRİ ===\n")
#> === R-DA RƏNG SİSTEMLƏRİ ===
# 1. Built-in color names
plot(1:10, 1:10, 
     main = "Built-in Rəng Adları",
     xlab = "X", ylab = "Y",
     pch = 19, cex = 2,
     col = c("red", "blue", "green", "yellow", "purple", 
             "orange", "pink", "brown", "gray", "black"))

# Show available colors
cat("Mövcud rəng sayı:", length(colors()), "\n")
#> Mövcud rəng sayı: 657
cat("İlk 20 rəng adı:", paste(colors()[1:20], collapse = ", "), "\n")
#> İlk 20 rəng adı: white, aliceblue, antiquewhite, antiquewhite1, antiquewhite2, antiquewhite3, antiquewhite4, aquamarine, aquamarine1, aquamarine2, aquamarine3, aquamarine4, azure, azure1, azure2, azure3, azure4, beige, bisque, bisque1
# 2. RGB və Hex colors
par(mfrow = c(2, 2))

# RGB colors (0-1 scale)
plot(1:5, 1:5,
     main = "RGB Rənglər",
     col = c(rgb(1, 0, 0), rgb(0, 1, 0), rgb(0, 0, 1), 
             rgb(1, 1, 0), rgb(1, 0, 1)),
     pch = 19, cex = 3)

# Hex colors
plot(1:5, 1:5,
     main = "Hex Rənglər",
     col = c("#FF0000", "#00FF00", "#0000FF", "#FFFF00", "#FF00FF"),
     pch = 19, cex = 3)

# Rainbow palette
plot(1:10, 1:10,
     main = "Rainbow Palette",
     col = rainbow(10),
     pch = 19, cex = 2)

# Heat colors
plot(1:10, 1:10,
     main = "Heat Colors",
     col = heat.colors(10),
     pch = 19, cex = 2)

par(mfrow = c(1, 1))

# 3. Color palettes showcase
showcase_palettes <- function() {
  par(mfrow = c(2, 3))
  
  n_colors <- 8
  x <- 1:n_colors
  y <- rep(1, n_colors)
  
  # Rainbow
  plot(x, y, col = rainbow(n_colors), pch = 19, cex = 3,
       main = "rainbow()", ylim = c(0, 2), xlab = "", ylab = "")
  
  # Heat colors
  plot(x, y, col = heat.colors(n_colors), pch = 19, cex = 3,
       main = "heat.colors()", ylim = c(0, 2), xlab = "", ylab = "")
  
  # Terrain colors
  plot(x, y, col = terrain.colors(n_colors), pch = 19, cex = 3,
       main = "terrain.colors()", ylim = c(0, 2), xlab = "", ylab = "")
  
  # Topo colors
  plot(x, y, col = topo.colors(n_colors), pch = 19, cex = 3,
       main = "topo.colors()", ylim = c(0, 2), xlab = "", ylab = "")
  
  # CM colors
  plot(x, y, col = cm.colors(n_colors), pch = 19, cex = 3,
       main = "cm.colors()", ylim = c(0, 2), xlab = "", ylab = "")
  
  # Custom palette
  custom_colors <- colorRampPalette(c("darkblue", "lightblue", "white", "lightpink", "darkred"))
  plot(x, y, col = custom_colors(n_colors), pch = 19, cex = 3,
       main = "Custom Palette", ylim = c(0, 2), xlab = "", ylab = "")
  
  par(mfrow = c(1, 1))
}

showcase_palettes()

# 4. Transparency and alpha values
transparency_demo <- function() {
  plot(1:20, 1:20, type = "n",
       main = "Rəng Şəffaflığı (Alpha) Nümayişi",
       xlab = "X", ylab = "Y")
  
  # Different alpha values
  for(i in 1:10) {
    alpha_val <- i / 10
    points(i, 10, col = rgb(1, 0, 0, alpha = alpha_val), 
           pch = 19, cex = 3)
    text(i, 8, paste(alpha_val), cex = 0.8)
  }
  
  # Overlapping points with transparency
  set.seed(123)
  x_random <- rnorm(100, 15, 2)
  y_random <- rnorm(100, 15, 2)
  
  points(x_random, y_random, 
         col = rgb(0, 0, 1, alpha = 0.3), 
         pch = 19, cex = 2)
  
  text(15, 5, "Şəffaf Nöqtələr\n(alpha = 0.3)", 
       col = "blue", font = 2)
}

transparency_demo()

# 5. Faculty-specific color coding
faculty_color_scheme <- function(data) {
  # Create consistent color scheme for faculties
  faculties <- unique(data$faculty)
  faculty_colors <- c(
    "Mühəndislik" = "#1f77b4",    # Blue
    "Tibb" = "#ff7f0e",           # Orange  
    "İqtisadiyyat" = "#2ca02c",   # Green
    "Hüquq" = "#d62728",          # Red
    "IT" = "#9467bd",             # Purple
    "Təbiət" = "#8c564b"          # Brown
  )
  
  plot(data$math_score, data$physics_score,
       main = "Fakültə Rəng Sxemi",
       xlab = "Riyaziyyat", ylab = "Fizika",
       col = faculty_colors[data$faculty],
       pch = 19, cex = 1.5)
  
  legend("bottomright",
         legend = names(faculty_colors),
         col = faculty_colors,
         pch = 19,
         bg = "white",
         cex = 0.9)
  
  return(faculty_colors)
}

colors_used <- faculty_color_scheme(viz_data)

# 6. Color gradient for continuous variables
gradient_plot <- function(x, y, z, main_title) {
  # Create color gradient based on third variable
  color_palette <- colorRampPalette(c("blue", "white", "red"))
  n_colors <- 100
  colors <- color_palette(n_colors)
  
  # Map z values to color indices
  z_scaled <- (z - min(z, na.rm = TRUE)) / (max(z, na.rm = TRUE) - min(z, na.rm = TRUE))
  color_indices <- round(z_scaled * (n_colors - 1)) + 1
  
  plot(x, y,
       main = main_title,
       col = colors[color_indices],
       pch = 19, cex = 1.5)
  
  # Add color legend
  legend_colors <- colors[seq(1, n_colors, length.out = 5)]
  legend_values <- round(seq(min(z, na.rm = TRUE), max(z, na.rm = TRUE), length.out = 5), 1)
  
  legend("topright",
         legend = legend_values,
         col = legend_colors,
         pch = 19,
         title = deparse(substitute(z)),
         bg = "white")
}

# Test gradient plot
gradient_plot(viz_data$study_hours_week, viz_data$gpa, viz_data$satisfaction_score,
             "Oxu Saatları vs GPA (Məmnuniyyət Rəngi)")

14.1 Point shapes və sizes

# === POINT SHAPES VƏ SİZES ===

cat("=== POINT CUSTOMIZATION ===\n")
#> === POINT CUSTOMIZATION ===
# 1. Different point shapes (pch)
par(mfrow = c(2, 2))

# Basic point shapes (0-25)
plot(1:26, rep(1, 26), 
     pch = 0:25, cex = 2,
     main = "Point Shapes (pch = 0:25)",
     xlab = "pch value", ylab = "",
     col = "darkblue")
text(1:26, rep(0.7, 26), 0:25, cex = 0.7)

# Different sizes
sizes <- c(0.5, 1, 1.5, 2, 2.5, 3)
plot(1:6, rep(1, 6),
     pch = 19, cex = sizes,
     main = "Point Sizes (cex)",
     xlab = "Size", ylab = "",
     col = "red")
text(1:6, rep(0.5, 6), sizes, cex = 0.8)

# Filled vs empty shapes
plot(1:10, rep(1, 10),
     pch = c(1, 16, 2, 17, 0, 15, 5, 18, 6, 8),
     cex = 2.5,
     main = "Filled vs Empty Shapes",
     col = rainbow(10))

# Combined shape and color coding
plot(viz_data$math_score, viz_data$physics_score,
     pch = ifelse(viz_data$gender == "Kişi", 17, 19),
     col = ifelse(viz_data$scholarship, "gold", "gray"),
     cex = viz_data$age / 12,
     main = "Shape + Color + Size Coding",
     xlab = "Riyaziyyat", ylab = "Fizika")

legend("bottomright",
       legend = c("Kişi (Təqaüdlü)", "Kişi (Təqaüdsüz)", 
                  "Qadın (Təqaüdlü)", "Qadın (Təqaüdsüz)"),
       pch = c(17, 17, 19, 19),
       col = c("gold", "gray", "gold", "gray"),
       bg = "white")

par(mfrow = c(1, 1))

# 2. Advanced point customization
advanced_point_plot <- function(data) {
  # Create sophisticated scatter plot
  plot(data$study_hours_week, data$gpa,
       main = "Qabaqcıl Point Customization",
       xlab = "Həftəlik Oxu Saatları",
       ylab = "GPA",
       
       # Shape by faculty
       pch = c(15, 16, 17, 18, 19, 8)[as.numeric(as.factor(data$faculty))],
       
       # Color by gender
       col = ifelse(data$gender == "Kişi", "blue", "red"),
       
       # Size by age
       cex = (data$age - 17) / 5 + 0.8,
       
       # Background color for scholarship
       bg = ifelse(data$scholarship, "yellow", "white"))
  
  # Add legends
  legend("topleft",
         legend = unique(data$faculty),
         pch = c(15, 16, 17, 18, 19, 8),
         col = "black",
         title = "Fakültə",
         bg = "white",
         cex = 0.8)
  
  legend("bottomright",
         legend = c("Kişi", "Qadın", "Təqaüdlü"),
         pch = c(19, 19, 21),
         col = c("blue", "red", "black"),
         pt.bg = c("white", "white", "yellow"),
         title = "Cins/Təqaüd",
         bg = "white",
         cex = 0.8)
}

advanced_point_plot(viz_data)

# 3. Point border and fill combinations
border_fill_demo <- function() {
  x <- rep(1:5, each = 4)
  y <- rep(1:4, 5)
  
  # Different border/fill combinations
  borders <- rep(c("black", "red", "blue", "green"), 5)
  fills <- rep(c("white", "yellow", "lightblue", "lightgreen", "pink"), each = 4)
  
  plot(x, y,
       pch = 21,  # Circle with border
       col = borders,
       bg = fills,
       cex = 3,
       main = "Border və Fill Kombinasiyaları",
       xlab = "Fill Colors", ylab = "Border Colors")
  
  # Add grid
  grid(col = "lightgray", lty = "dotted")
}

border_fill_demo()

# 4. Size coding for bubble plots
bubble_plot_demo <- function(data) {
  # Normalize age for bubble sizes
  age_normalized <- (data$age - min(data$age)) / (max(data$age) - min(data$age))
  bubble_sizes <- age_normalized * 3 + 0.5  # Scale to reasonable size range
  
  plot(data$family_income, data$satisfaction_score,
       main = "Bubble Plot: Gəlir vs Məmnuniyyət\n(Qabar ölçüsü: Yaş)",
       xlab = "Ailə Gəliri (AZN)",
       ylab = "Məmnuniyyət Səviyyəsi",
       
       pch = 21,
       col = "darkblue",
       bg = rgb(0, 0, 1, alpha = 0.3),
       cex = bubble_sizes)
  
  # Add size legend
  legend_sizes <- c(0.8, 1.5, 2.2, 3.0)
  legend_ages <- round(seq(min(data$age), max(data$age), length.out = 4))
  
  legend("topright",
         legend = paste(legend_ages, "yaş"),
         pch = 21,
         pt.cex = legend_sizes,
         col = "darkblue",
         pt.bg = rgb(0, 0, 1, alpha = 0.3),
         title = "Yaş",
         bg = "white")
}

bubble_plot_demo(viz_data)

14.2 Text və annotations

# === TEXT VƏ ANNOTATİONS ===

cat("=== TEXT VƏ ANNOTATİONS ===\n")
#> === TEXT VƏ ANNOTATİONS ===
# 1. Basic text annotations
plot(viz_data$math_score, viz_data$physics_score,
     main = "Text Annotations Nümayişi",
     xlab = "Riyaziyyat Nəticəsi",
     ylab = "Fizika Nəticəsi",
     pch = 19, col = "lightblue")

# Add correlation text
correlation <- cor(viz_data$math_score, viz_data$physics_score, use = "complete.obs")
text(50, 90, paste("Correlation: r =", round(correlation, 3)), 
     font = 2, cex = 1.2, col = "red")

# Add regression line and equation
lm_model <- lm(physics_score ~ math_score, data = viz_data)
abline(lm_model, col = "red", lwd = 2)

# Extract equation parameters
slope <- round(coef(lm_model)[2], 3)
intercept <- round(coef(lm_model)[1], 3)
r_squared <- round(summary(lm_model)$r.squared, 3)

equation_text <- paste("y =", slope, "x +", intercept)
r_sq_text <- paste("R² =", r_squared)

text(50, 85, equation_text, font = 2, cex = 1.1, col = "red")
text(50, 80, r_sq_text, font = 2, cex = 1.1, col = "red")

# 2. Text positioning and formatting
text_positioning_demo <- function() {
  plot(1:5, 1:5, type = "n",
       main = "Text Positioning Seçimləri",
       xlab = "X", ylab = "Y")
  
  # Central point
  points(3, 3, pch = 19, cex = 2, col = "red")
  
  # Different positions around the point
  text(3, 3, "pos=1", pos = 1, col = "blue", font = 2)  # Below
  text(3, 3, "pos=2", pos = 2, col = "green", font = 2) # Left
  text(3, 3, "pos=3", pos = 3, col = "purple", font = 2) # Above
  text(3, 3, "pos=4", pos = 4, col = "orange", font = 2) # Right
  
  # Different text sizes and fonts
  text(1, 4.5, "cex=0.5", cex = 0.5)
  text(1, 4.0, "cex=1.0", cex = 1.0)
  text(1, 3.5, "cex=1.5", cex = 1.5)
  text(1, 3.0, "cex=2.0", cex = 2.0)
  
  text(4.5, 4.5, "font=1 (normal)", font = 1)
  text(4.5, 4.0, "font=2 (bold)", font = 2)
  text(4.5, 3.5, "font=3 (italic)", font = 3)
  text(4.5, 3.0, "font=4 (bold italic)", font = 4)
}

text_positioning_demo()

# 3. Labeling outliers
label_outliers <- function(x, y, labels, threshold = 2) {
  # Calculate z-scores
  z_x <- abs(scale(x))
  z_y <- abs(scale(y))
  
  # Identify outliers
  outliers <- z_x > threshold | z_y > threshold
  
  plot(x, y,
       main = paste("Outlier Labeling (threshold =", threshold, "SD)"),
       pch = ifelse(outliers, 17, 19),
       col = ifelse(outliers, "red", "steelblue"),
       cex = ifelse(outliers, 1.5, 1.0))
  
  # Label outliers
  if(any(outliers, na.rm = TRUE)) {
    text(x[outliers], y[outliers], labels[outliers],
         pos = 3, col = "red", font = 2, cex = 0.8)
  }
  
  # Add legend
  legend("topright",
         legend = c("Normal", "Outlier"),
         pch = c(19, 17),
         col = c("steelblue", "red"),
         bg = "white")
}

label_outliers(viz_data$family_income, viz_data$satisfaction_score, 
               viz_data$name, threshold = 1.5)

# 4. Mathematical expressions
math_expressions_demo <- function() {
  plot(1:10, (1:10)^2,
       main = "Riyazi İfadələr",
       xlab = "x",
       ylab = expression(x^2),
       pch = 19, col = "blue")
  
  # Add mathematical expressions
  text(5, 80, expression(y == x^2), cex = 1.5, font = 2)
  text(7, 40, expression(sigma == sqrt(frac(sum((x - mu)^2), n-1))), 
       cex = 1.2, col = "red")
  text(2, 60, expression(paste("Correlation: ", rho, " = 0.95")), 
       cex = 1.1, col = "darkgreen")
  
  # Greek letters
  text(8, 20, expression(alpha + beta + gamma + delta), cex = 1.3)
}

math_expressions_demo()

# 5. Annotations with arrows and boxes
annotated_plot <- function(data) {
  plot(data$study_hours_week, data$gpa,
       main = "Annotated Analysis Plot",
       xlab = "Həftəlik Oxu Saatları",
       ylab = "GPA",
       pch = 19, col = "lightblue")
  
  # Find interesting points
  high_achiever <- which.max(data$gpa)
  low_study_high_gpa <- which(data$study_hours_week < 20 & data$gpa > 3.5)[1]
  
  # Point to high achiever
  if(!is.na(high_achiever)) {
    arrows(x0 = data$study_hours_week[high_achiever] + 5, 
           y0 = data$gpa[high_achiever] - 0.2,
           x1 = data$study_hours_week[high_achiever], 
           y1 = data$gpa[high_achiever],
           col = "red", lwd = 2, length = 0.1)
    
    text(data$study_hours_week[high_achiever] + 5, 
         data$gpa[high_achiever] - 0.2,
         "Ən yüksək GPA", pos = 4, col = "red", font = 2)
  }
  
  # Box around efficient learner
  if(!is.na(low_study_high_gpa)) {
    rect(data$study_hours_week[low_study_high_gpa] - 2,
         data$gpa[low_study_high_gpa] - 0.1,
         data$study_hours_week[low_study_high_gpa] + 2,
         data$gpa[low_study_high_gpa] + 0.1,
         border = "green", lwd = 2)
    
    text(data$study_hours_week[low_study_high_gpa],
         data$gpa[low_study_high_gpa] - 0.3,
         "Səmərəli\nTələbə", pos = 1, col = "green", font = 2)
  }
  
  # Add trend line with confidence interval
  lm_model <- lm(gpa ~ study_hours_week, data = data)
  abline(lm_model, col = "blue", lwd = 2)
  
  # Add equation
  slope <- round(coef(lm_model)[2], 4)
  intercept <- round(coef(lm_model)[1], 3)
  
  text(35, 2.5, paste("GPA =", intercept, "+", slope, "× Hours"),
       bg = "white", col = "blue", font = 2, cex = 1.1)
}

annotated_plot(viz_data)

# 6. Multi-language text support
multilingual_demo <- function() {
  plot(1:5, 1:5, type = "n",
       main = "Çoxdilli Mətn Dəstəyi",
       xlab = "", ylab = "")
  
  # Different languages and scripts
  text(1, 4, "English Text", cex = 1.2)
  text(2, 4, "Azərbaycan Mətni", cex = 1.2)
  text(3, 4, "Текст на русском", cex = 1.2)
  text(4, 4, "Türkçe Metin", cex = 1.2)
  
  # Mathematical and special characters
  text(2.5, 3, "α β γ δ ε π σ μ λ", cex = 1.5, col = "blue")
  text(2.5, 2, "∑ ∏ ∫ ∞ ± ≠ ≤ ≥", cex = 1.5, col = "red")
  text(2.5, 1, "← → ↑ ↓ ↔ ⇔", cex = 1.5, col = "green")
}

multilingual_demo()


15 🎯 Modulun Xülasəsi və Növbəti Addımlar

🎉 Modul 8 Uğurla Başa Çatdı!

✅ Mənimsədiyiniz Biliklər

  • Base R plot() funksiyasının bütün imkanları
  • Scatter, line, bar, histogram, boxplot qrafikləri
  • Rəng sistemləri və paletlər
  • Point shapes, sizes və customization
  • Text annotations və mathematical expressions

🛠️ Praktik Bacarıqlar

  • Professional vizualizasiya yaratma
  • Multi-dimensional data representation
  • Outlier detection və highlighting
  • Statistical overlay əlavə etmə
  • Publication-ready plots hazırlama

🚀 Növbəti Mərhələ

  • ggplot2 paketi ilə advanced visualization
  • İnteraktiv qrafiklər (plotly)
  • Dashboard yaratma (shiny)
  • 3D visualization techniques
  • Animation və dynamic plots

💎 Key Takeaways

  • plot() universal və adaptiv funksiyadır
  • Rəng seçimi data interpretation-ı təsir edir
  • Annotations qrafikləri daha informativ edir
  • Visual encoding multiple variables göstərə bilər

15.1 🏠 Ev Tapşırığı və Praktika

📋 Visualization Challenge

15.1.0.1 🔧 Praktik Tapşırıqlar

  1. Personal Data Visualization

    # Öz məlumatlarınızla dataset yaradın və vizualizasiya edin
    my_data <- data.frame(
      date = seq(as.Date("2024-01-01"), as.Date("2024-12-31"), by = "month"),
      expense = c(800, 750, 900, 850, 800, 950, 1000, 900, 850, 800, 950, 1200),
      income = c(2000, 2100, 2000, 2200, 2300, 2100, 2400, 2200, 2100, 2300, 2200, 2500),
      mood = sample(1:10, 12, replace = TRUE)
    )
    
    # Bu data ilə 5 fərqli qrafik növü yaradın
  2. Advanced Scatter Plot

    • mtcars dataset istifadə edərək
    • 4+ dəyişəni eyni qrafikdə göstərin
    • Professional legend və annotations əlavə edin
  3. Color Story

    • Özünüz üçün rəng paleti yaradın
    • Faculty performance müqayisəsi edin
    • Meaningful color coding istifadə edin

15.1.0.2 🎯 Yaradıcı Challenge

“Data Art” Project: Məlumatlarınızı istifadə edərək estetik və informativ qrafik yaradın ki, həm analitik dəyəri, həm də vizual cəlbediciliyi olsun.


🎨 Visualization Master!

Artıq siz Base R ilə professional səviyyədə vizualizasiya yarada bilərsiniz. Növbəti mərhələdə ggplot2 ilə daha da advanced techniques öyrənəcəksiniz!

🎯 Remember: “A picture is worth a thousand words” - vizualizasiya data science-in ən güçlü vasitələrindən biridir!